<!--
 * @Author: MuQuanyu(MQy)
 * @Date: 2025-10-10 16:39:36
 * @LastEditTime: 2025-10-23 14:16:42
 * @email: muquanyu@outlook.com
-->
<template>
  <div class="org-manager-box">
    <el-dialog class="custom-dialog" v-model="orgDialogVisible" :title="isEdit ? '编辑组织' : '添加组织'"
      :before-close="orgDialogClose">
      <el-form v-loading="isDialogLoading" style="padding: 15px" ref="orgDialogFormRef" :model="orgForm"
        :rules="orgRules" label-width="auto">
        <el-row justify="space-between">
          <el-col :span="11">
            <el-form-item label="组织名" prop="name">
              <el-input v-model="orgForm.name"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="11">
            <el-form-item label="组织代码" prop="code">
              <el-input v-model="orgForm.code"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row justify="space-between">
          <el-col :span="11">
            <el-form-item label="组织领导" prop="directorId">
              <el-dropdown trigger="click" ref="sasListDropdownRef" @visible-change="sasListDropdownVisChange">
                <el-input class="readonly-pointer-input" readonly v-model="orgForm.directorName"></el-input>
                <template #dropdown>
                  <SearchAndSelectList @radio-select="sasRadioSelect" @loading="sasLoading" @search="sasSearch"
                    :is-loading="sasIsLoading" :is-radio="true" :data-list="sasList" search-placeholder="请输入搜索内容">
                  </SearchAndSelectList>
                </template>
              </el-dropdown>
            </el-form-item>
          </el-col>
          <el-col :span="11">
            <!-- 一般组织数据都不会太多，一次性加载就行 -->
            <el-form-item label="上级组织" prop="parentId">
              <el-cascader popper-class="loading" v-model="selectedOrgCascader" :props="{
                value: 'id',
                label: 'name',
                checkStrictly: true
              }" :options="leftOrgData" @change="orgCascaderChange" @visible-change="orgCascaderVisibleChange"
                placeholder="请选择（默认顶级）" clearable />
              <!-- <el-input v-model="addOrgForm.parentId"></el-input> -->
            </el-form-item>
          </el-col>
        </el-row>
        <el-row justify="space-between">
          <el-col :span="11">
            <el-form-item label="组织分类" prop="category">
              <el-select v-model="orgForm.category" filterable placeholder="请选择分类" style="width: 240px">
                <el-option v-for="item in dictDataList" :key="item.dictCode" :label="item.dictLabel"
                  :value="item.dictCode" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="11">
            <el-form-item label="备注" prop="remark">
              <el-input type="textarea" v-model="orgForm.remark"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row justify="space-between">
          <el-col :span="22">
            <el-form-item label="状态" prop="status">
              <el-radio-group v-model="orgForm.status">
                <el-radio :value="1">开启</el-radio>
                <el-radio :value="0">禁用</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div class="dialog-bottom" style="display: flex; align-items: center; justify-content: flex-end">
        <el-button :disabled="isDialogLoading" @click="orgDialogClose">取消</el-button>
        <el-button :disabled="isDialogLoading" type="primary" @click="orgConfirm">确定</el-button>
      </div>
    </el-dialog>

    <el-card class="left-card">
      <div class="lc-header">
        <el-input clearable v-model="leftOrgSearchKey" style="width: 240px" placeholder="请输入组织名"
          :suffix-icon="Search" />
        <el-dropdown placement="bottom">
          <el-button>
            <el-icon>
              <More />
            </el-icon>
          </el-button>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item @click="expandAllLeftOrgNode">全部展开</el-dropdown-item>
              <el-dropdown-item @click="collapsaAllLeftOrgNode">全部折叠</el-dropdown-item>
              <el-dropdown-item @click="cancelCurrentLeftOrgNode">取消选中</el-dropdown-item>
              <el-dropdown-item @click="refreshLeftOrgList">刷新</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>

      </div>
      <div class="left-tree-outer-box" v-loading="leftOrgLoading">
        <el-tree :default-expand-all="isExpandAllLeftOrgNode" :filter-node-method="filterNode" ref="leftOrgRef"
          :data="leftOrgData" :props="defaultProps" highlight-current :current-node-key="currentOrgNodeKey"
          :expand-on-click-node="false" node-key="id" @node-click="handleOrgTreeClick" style="width: 100%">
          <template #empty>
            <div style="display: flex; flex-direction: column; gap: 10px; align-items: center">
              <i class="iconfont icon-kongshuju" style="font-size: 100px"></i>
              <span>空数据</span>
            </div>
          </template>
        </el-tree>
      </div>
    </el-card>
    <el-card class="right-card">
      <div class="rc-top-operator">
        <el-input v-model="rightOrgSearchKey" style="width: 240px" placeholder="请输入组织名" :suffix-icon="Search" />
        <el-button @click="searchRightOrgList">搜索</el-button>
        <el-button @click="showAddDialog" type="primary">添加</el-button>
        <el-button @click="openDleteMBox" type="danger">批量删除</el-button>
        <el-button @click="resetRightOrgList" type="warning">重置</el-button>
      </div>
      <el-table :header-cell-style="{ background: 'var(--yu-div-hover-gray)', color: 'var(--yu-text-color)' }"
        v-loading="orgTableLoading" class="el-table-outer" border height="calc(100vh - 250px)" ref="orgTableRef"
        :data="orgTableData" row-key="id" style="width: 100%" @selection-change="handleSelectionChange">
        <template #empty>
          <div style="display: flex; flex-direction: column; gap: 10px; align-items: center">
            <i class="iconfont icon-kongshuju" style="font-size: 100px"></i>
            <span>空数据</span>
          </div>
        </template>
        <!--  :selectable="(row: any) => !selectedItems.includes(row.id)" -->
        <el-table-column type="selection" width="55" />
        <el-table-column label="组织名" width="120">
          <template #default="scope">{{ scope.row.name }}</template>
        </el-table-column>
        <el-table-column label="组织代码" property="code"></el-table-column>
        <el-table-column label="分类" property="category">
          <template #default="scope">
            {{dictDataList.find((x: any) => x.dictCode == scope.row.category)?.dictLabel}}
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template #default="scope">
            <div style="display: flex; align-items: center; gap: 5px; justify-content: center;">
              <el-button type="text" @click="showEditDialog(scope.row.id)">修改</el-button>
              <DeletePopconfirm @handle-delete="deleteSignle" :row-data="scope.row" :loading="isOrgDeleteSingleLoading">

              </DeletePopconfirm>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <div class="custom-pagination-box">
        <el-pagination v-model:current-page="orgTablePageObj.page" v-model:page-size="orgTablePageObj.pageSize"
          :page-sizes="[10, 20, 30, 40]" :size="'default'" :disabled="false" :background="false"
          layout="total, sizes, prev, pager, next, jumper" :total="orgTablePageObj.total"
          @size-change="handleSizeChange" @current-change="handleCurrentChange" />
      </div>

    </el-card>
  </div>
</template>

<script setup lang="ts">

import { Search } from "@element-plus/icons-vue";
import { ElLoading, ElMessage, ElMessageBox, type FormInstance, type FormRules } from "element-plus";
import { onMounted, reactive, ref, watch } from "vue";
import SearchAndSelectList from "@/components/SearchAndSelectList/index.vue";
import type { User } from "@/api/sys/user/types";
import { GetUserPage } from "@/api/sys/user";
import DeletePopconfirm from '@/components/DeletePopconfirm/index.vue'
import { AddOrg, DeleteOrg, EditOrg, GetOrgFlatPage, GetOrgTreeList, OrgDetail } from "@/api/sys/org"
import { DictDataList } from "@/api/sys/dict";

const isExpandAllLeftOrgNode = ref(true)
const leftOrgSearchKey = ref<string>("");
const rightOrgSearchKey = ref<string | null>(null);
const orgDialogVisible = ref(false);
const sasListDropdown = ref(null)
const defaultProps = {
  children: "children",
  label: "name",
};
const leftOrgRef = ref();
const currentOrgNodeKey = ref(null);
const leftOrgData = ref<any>(
);

const handleOrgTreeClick = async (node: any) => {
  if (currentOrgNodeKey.value == node.id) {
    currentOrgNodeKey.value = null;
    leftOrgRef.value.setCurrentKey(null);

  } else {
    currentOrgNodeKey.value = node.id;
    leftOrgRef.value.setCurrentKey(node.id);

  }
  await fetchOrgTableData()
  console.log("handleDeptTreeClick", currentOrgNodeKey.value);
};
//#region 添加组织
const orgDialogClose = () => {
  orgDialogFormRef.value?.resetFields();
  orgForm.value = {
    name: "",
    code: "",
    directorId: "0",
    directorName: "",
    parentId: "0",
    parentName: "",
    category: "",
    categoryName: "",
    remark: "",
    status: 1,
  }
  selectedOrgCascader.value = []
  orgDialogVisible.value = false;
};
const showAddDialog = async () => {
  isEdit.value = false;
  orgDialogVisible.value = true;
  isDialogLoading.value = true;
  await initLeftOrgTreeList()
  isDialogLoading.value = false;
};
const currentEditOrgId = ref<any>(null)
const isDialogLoading = ref(false)
const showEditDialog = async (id: string) => {
  currentEditOrgId.value = id
  isEdit.value = true;
  orgDialogVisible.value = true;
  isDialogLoading.value = true;
  await initLeftOrgTreeList()
  leftOrgRef.value.filter(leftOrgSearchKey.value.trim()) // 还得过滤
  // 查询组织详情
  let res = await OrgDetail(id)
  if (res.code == 200) {
    orgForm.value = {
      name: res.data.name,
      code: res.data.code,
      directorId: res.data.directorId,
      directorName: res.data.directorName,
      parentId: res.data.parentId,
      parentName: res.data.parentName,
      category: res.data.category,
      categoryName: res.data.category,
      remark: res.data.remark,
      status: res.data.status ? 1 : 0,
    }
  }
  if (orgForm.value.parentId != null && orgForm.value.parentId != "0") {
    isFindFlag.value = false;
    selectedOrgCascader.value = []
    parentOrgPathPos.value = 0
    console.log(orgForm.value.parentId)
    findParentOrgPathArr(leftOrgData.value, orgForm.value.parentId)
    console.log(selectedOrgCascader.value)
  }

  isDialogLoading.value = false;
}

const orgDialogFormRef = ref<FormInstance>();
interface OrgForm {
  name: string;
  code: string;
  directorId: string;
  directorName: string;
  parentId: string;
  parentName: string;
  category: string; // 分类的字段值
  categoryName: string;
  remark: string;
  status: number;
}
const orgForm = ref<OrgForm>({
  name: "",
  code: "",
  directorId: "0",
  directorName: "",
  parentId: "0",
  parentName: "",
  category: "",
  categoryName: "",
  remark: "",
  status: 1,
});
const orgRules = reactive<FormRules<OrgForm>>({
  name: [{ required: true, message: "组织名必填", trigger: "blur" }],
  code: [{ required: true, message: "组织编号必填", trigger: "blur" }],
  category: [{ required: true, message: "组织分类必填", trigger: "blur" }],
});
const isEdit = ref(false)
const orgConfirm = async () => {
  try {
    await orgDialogFormRef.value?.validate()
  } catch (err: any) {
    return;
  }
  if (isEdit.value) {
    let res: any = await EditOrg({
      id: currentEditOrgId.value,
      name: orgForm.value.name,
      code: orgForm.value.code,
      directorId: orgForm.value.directorId,
      parentId: orgForm.value.parentId,
      category: orgForm.value.category,
      remark: orgForm.value.remark,
      status: orgForm.value.status == 1,
    })
    if (res.code == 200) {
      ElMessage.success("修改成功")
    }
  } else {
    let res: any = await AddOrg({
      name: orgForm.value.name,
      code: orgForm.value.code,
      directorId: orgForm.value.directorId,
      parentId: orgForm.value.parentId,
      category: orgForm.value.category,
      remark: orgForm.value.remark,
      status: orgForm.value.status == 1,
    })
    if (res.code == 200) {
      ElMessage.success("添加成功")
    }
  }

  orgDialogClose()
  await initLeftOrgTreeList();
  await fetchOrgTableData();
  leftOrgRef.value.filter(leftOrgSearchKey.value.trim())
}
//#endregion
//#region 组织领导选择
const sasPageObj = ref({
  page: 1,
  pageSize: 10,
  total: 0,
  pages: 0
})
const sasIsLoading = ref(false)
const sasList = ref<User[]>()

const sasLoading = async () => {
  sasIsLoading.value = true;
  try {
    let res: any = await GetUserPage({
      page: sasPageObj.value.page,
      pageSize: sasPageObj.value.pageSize
    })
    if (res.code == 200) {
      if (sasPageObj.value.page == 1) {
        sasList.value = []
      }
      res.data.list.forEach((element: any) => {
        element.title = element.nickname;
        element.imgUrl = element.headPic;
      });
      sasList.value?.push(...res.data.list)
      sasPageObj.value.pages = res.data.pages
      sasPageObj.value.total = res.data.total
    }
  } catch (error) {
    ElMessage.error("加载失败")
  } finally {
    sasIsLoading.value = false;
  }
}
const sasListDropdownVisChange = async (vis: any) => {
  if (vis && sasPageObj.value.page == 1) {
    sasPageObj.value.page = 1
    sasIsLoading.value = true;
    try {
      let res: any = await GetUserPage({
        page: sasPageObj.value.page,
        pageSize: sasPageObj.value.pageSize
      })
      if (res.code == 200) {
        if (sasPageObj.value.page == 1) {
          sasList.value = []
        }
        res.data.list.forEach((element: any) => {
          element.title = element.nickname;
          element.imgUrl = element.headPic;
        });
        sasList.value?.push(...res.data.list)
        sasPageObj.value.page++
        sasPageObj.value.pages = res.data.pages
        sasPageObj.value.total = res.data.total
      }
    } catch (error) {
      ElMessage.error("加载失败")
    } finally {
      sasIsLoading.value = false;
    }
  }
}
const sasListDropdownRef = ref<any>(null)
const sasRadioSelect = (item: any) => {
  if (isEdit.value) {
    // 编辑
  } else {
    orgForm.value.directorId = item.id
    orgForm.value.directorName = item.nickname
  }
  sasListDropdownRef.value?.handleClose()

  console.log(item)
}
const sasSearch = (searchKey: string) => {
  console.log(searchKey)
}
//#endregion
//#region 上级组织
const orgCascaderLoading = ref<any>(null)
const orgCascaderOptions = ref()
const orgCascaderVisibleChange = async (isShow: any) => {
  if (isShow) {
    // let options = {
    //   target: '.loading',
    //   lock: true,
    //   text: "加载中..."
    // }
    // orgCascaderLoading.value = ElLoading.service(options)
    let res: any = await GetOrgTreeList()
    if (res.code == 200) {
      orgCascaderOptions.value = []
      res.data.forEach((x: any) => {
        orgCascaderOptions.value.push(x)
      });

    }
    // orgCascaderLoading.value.close();
  }
}
const selectedOrgCascader = ref<any>([])
const orgCascaderChange = (e: any) => {
  console.log(e)
  if (e && e.length > 0) {
    orgForm.value.parentId = e[e.length - 1]
  } else {
    orgForm.value.parentId = "0"
  }
}
// a => b =>
const isFindFlag = ref(false)
const parentOrgPathPos = ref(0)
const findParentOrgPathArr = (data: any, id: string) => {
  if (isFindFlag.value) return;
  for (let i = 0; i < data.length; ++i) {
    selectedOrgCascader.value[parentOrgPathPos.value] = data[i].id
    if (data[i].id == id) {
      isFindFlag.value = true;
      return;
    }
    parentOrgPathPos.value++
    findParentOrgPathArr(data[i].children, id)
    if (isFindFlag.value) return;
    parentOrgPathPos.value--;
  }


}

//#endregion
//#region 左侧org与table数据
const leftOrgLoading = ref(false)
const initLeftOrgTreeList = async () => {
  leftOrgLoading.value = true;
  let res: any = await GetOrgTreeList()
  if (res.code == 200) {
    leftOrgData.value = [];
    res.data?.forEach((x: any) => {
      leftOrgData.value.push(x)
    })
  }
  leftOrgLoading.value = false;
}
const orgTableLoading = ref(false)
// 搜索过滤 el-tree
watch(leftOrgSearchKey, (val: string) => {
  leftOrgRef.value.filter(leftOrgSearchKey.value.trim())
})

const filterNode = (value: any, data: any) => {
  if (!value) return true;
  const matchCurrent = data.name && data.name.includes(value)

  return matchCurrent
}

// 全部展开与折叠
const expandAllLeftOrgNode = () => {
  leftOrgRef.value.store._getAllNodes().forEach((x: any) => {
    x.expanded = true;
  })
}
const collapsaAllLeftOrgNode = () => {
  leftOrgRef.value.store._getAllNodes().forEach((x: any) => {
    x.expanded = false;
  })
}
// 取消选中与刷新
const cancelCurrentLeftOrgNode = async () => {
  if (currentOrgNodeKey.value != null) {
    currentOrgNodeKey.value = null;
    leftOrgRef.value.setCurrentKey(null);
    await fetchOrgTableData()
  }
}
const refreshLeftOrgList = async () => {
  currentOrgNodeKey.value = null;
  leftOrgRef.value.setCurrentKey(null);
  leftOrgLoading.value = true
  orgTableLoading.value = true
  await initLeftOrgTreeList()
  await fetchOrgTableData()
}



// 组织表格分页记录实体
const orgTablePageObj = reactive({
  page: 1,
  pageSize: 10,
  total: 0,
  pages: 0
})
const orgTableData = ref<any>(null)
const firstDict = ref(false)
const dictDataList = ref()
const fetchOrgTableData = async () => {
  if (!firstDict.value) {
    let res = await DictDataList({
      dictTypeCode: 'ORG_CLASSIFY'
    })
    if (res.code == 200) {
      dictDataList.value = res.data
    }
    firstDict.value = true
  }
  orgTableLoading.value = true;
  let res: any = await GetOrgFlatPage({
    page: orgTablePageObj.page,
    pageSize: orgTablePageObj.pageSize,
    parentId: currentOrgNodeKey.value,
    searchKey: rightOrgSearchKey.value
  })
  if (res.code == 200) {
    orgTableData.value = [];
    res.data.list.forEach((x: any) => {
      orgTableData.value.push({
        ...x,
        isDeletedLoading: false
      })
    })
    orgTablePageObj.total = res.data.total;
    orgTablePageObj.pages = res.data.pages;
  }
  orgTableLoading.value = false;
}
const selectedOrgItems = ref<any>([])
const handleSelectionChange = (e: any) => {
  selectedOrgItems.value = e
}
// 分页组件
const handleSizeChange = async (e: any) => {
  sasPageObj.value.pageSize = e
  await fetchOrgTableData()
}
const handleCurrentChange = async (e: any) => {
  sasPageObj.value.page = e
  await fetchOrgTableData()
}
// 删除组织
const openDleteMBox = async () => {
  if (selectedOrgItems.value.length > 0) {
    ElMessageBox.confirm(
      '确认删除么?',
      '温馨提示',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )
      .then(async () => {
        const selectedIds = selectedOrgItems.value.map((x: any) => x.id)
        let res = await DeleteOrg({
          ids: selectedIds
        })
        if (res.code == 200) {
          ElMessage.success("删除成功！")
          await initLeftOrgTreeList()
          await fetchOrgTableData()
        }
      })
      .catch(() => {
      })
  } else {
    ElMessage.warning("请至少选择一项")
  }

}
const isOrgDeleteSingleLoading = ref(false)
const deleteSignle = async (e: any) => {
  console.log(e)
  let res = await DeleteOrg({
    ids: [e.id]
  })
  if (res.code == 200) {
    ElMessage.success("删除成功！")
    await initLeftOrgTreeList()
    await fetchOrgTableData()
  }
  leftOrgRef.value.filter(leftOrgSearchKey.value.trim())
}
// 搜索组织
const searchRightOrgList = async () => {
  if (!orgTableLoading.value) {
    sasPageObj.value.page = 1
    await fetchOrgTableData()
  }

}
const resetRightOrgList = async () => {
  if (!orgTableLoading.value) {
    rightOrgSearchKey.value = ""
    await fetchOrgTableData()
  }
}
//#endregion
onMounted(async () => {
  await initLeftOrgTreeList()
  orgTablePageObj.page = 1
  await fetchOrgTableData()
})
</script>

<style lang="scss" scoped>
.org-manager-box {
  height: 100%;
  display: flex;
  gap: 5px;

  .left-card {
    flex-grow: 1;
    max-width: 300px;

    .lc-header {
      gap: 5px;
      padding: 20px;
      display: flex;
      align-items: center;
      border-bottom: 1px solid var(--el-card-border-color);
    }

    .left-tree-outer-box {
      padding: 10px;
      overflow-y: auto;
    }
  }

  .right-card {
    flex-grow: 2;
    padding: 20px;
    display: flex;
    flex-direction: column;

    .rc-top-operator {
      display: flex;
      align-items: center;
      gap: 10px;
    }

    .el-table-outer {
      margin-top: 20px;
    }
  }
}

::v-deep(.el-card) {
  .el-card__body {
    padding: 0 !important;
  }
}
</style>
